﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace Mengsk.ProxyDelivery.HTTPHelpers
{
    public class HttpUtilEx
    {
        public static Regex REG_URL_ENCODING = new Regex(@"%[a-f0-9]{2}");

        public static string DoGet(string url, Encoding encoding, string accept = "", string refer = "", Dictionary<string, string> para = null, Dictionary<string, string> headers = null, Dictionary<string, string> cookies = null)
        {
            Uri uri = new Uri(url);
            string requestURL = url;
            if (para != null && para.Count > 0)
            {
                string requestPram = string.Join("&", para.Select(item => item.Key + "=" + UrlEncode(item.Value, Encoding.GetEncoding("utf-8"))));
                requestURL += "?" + requestPram;
            }
            HttpWebRequest httpPostRequest = (HttpWebRequest)(WebRequest.Create(requestURL));
            httpPostRequest.ServicePoint.Expect100Continue = false;
            httpPostRequest.KeepAlive = true;
            httpPostRequest.Method = "GET";
            httpPostRequest.KeepAlive = true;
            httpPostRequest.Timeout = 20 * 60000;
            httpPostRequest.Referer = refer;
            httpPostRequest.Accept = accept;
            //httpPostRequest.Connection = "keep-alive";
            httpPostRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0";
            //添加header
            if (headers != null)
            {
                foreach (var item in headers)
                {
                    httpPostRequest.Headers.Add(item.Key, item.Value);
                }
            }

            //添加cookie
            if (cookies != null)
            {
                httpPostRequest.CookieContainer = new CookieContainer();
                foreach (var item in cookies)
                {
                    httpPostRequest.CookieContainer.Add(new Cookie(item.Key, item.Value, "/", uri.Host));
                }
            }

            HttpWebResponse rsp = (HttpWebResponse)httpPostRequest.GetResponse();
            StreamReader reader = null;
            try
            {
                reader = new StreamReader(rsp.GetResponseStream(), encoding);
                string content = reader.ReadToEnd();
                return content;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
                rsp.Close();
            }
        }

        public static string DoGetWithRetry(int retry, string url, Encoding encoding, string accept = "", string refer = "", Dictionary<string, string> para = null, Dictionary<string, string> headers = null, Dictionary<string, string> cookies = null)
        {
            Exception lastException = null;

            //如果是在调试状态则只重试一次
            if (Debugger.IsAttached)
            {
                retry = 1;
            }
            for (int i = 0; i < retry; i++)
            {
                try
                {
                    return DoGet(url, encoding, accept, refer, para, headers, cookies);
                }
                catch (Exception ex)
                {
                    Thread.Sleep((i + 1) * 1500);
                    lastException = ex;
                }
            }
            throw lastException;
        }

        public static string UrlEncode(string str, Encoding e)
        {
            if (str == null)
            {
                return null;
            }

            String stringToEncode = HttpUtility.UrlEncode(str, e).Replace("+", "%20").Replace("*", "%2A").Replace("(", "%28").Replace(")", "%29");
            return REG_URL_ENCODING.Replace(stringToEncode, m => m.Value.ToUpperInvariant());
        }
    }
}
